package cn.com.dhcc.turbo.service.registry.sync.webservice;

import java.util.Date;
import java.util.List;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import cn.com.dhcc.app.core.CM;
import cn.com.dhcc.app.core.exception.ServiceException;
import cn.com.dhcc.app.core.service.BaseService;
import cn.com.dhcc.app.core.service.Log;
import cn.com.dhcc.app.core.service.Log.LOGTYPE;
import cn.com.dhcc.app.core.tag.CommonStaticCode.SUCCESSFAIL;
import cn.com.dhcc.app.core.tag.CommonStaticCode.YESNO;
import cn.com.dhcc.app.core.util.JsonUtil;
import cn.com.dhcc.app.core.util.UUIDGenerator;
import cn.com.dhcc.turbo.entity.registry.DomainInfo;
import cn.com.dhcc.turbo.entity.registry.ExchConnRequest;
import cn.com.dhcc.turbo.entity.registry.NodeInfo;
import cn.com.dhcc.turbo.entity.registry.NodePipeline;
import cn.com.dhcc.turbo.entity.registry.SynchronizeInfo;
import cn.com.dhcc.turbo.entity.registry.SynchronizeInfo.SyncType;
import cn.com.dhcc.turbo.service.registry.BaseInfoService;
import cn.com.dhcc.turbo.service.registry.LocalConfCallBack;
import cn.com.dhcc.turbo.service.registry.vo.NodeExchRelResponse;
import cn.com.dhcc.turbo.service.registry.vo.NodeExchRelVo;
/**
 * 
 * @author qiao
 * @2014-5-30 @上午10:01:55
 */
@Service("nodeCommunicateServiceImpl")
/*@WebService(endpointInterface = "cn.com.dhcc.turbo.service.registry.sync.webservice.NodeCommunicateInterface")*/
public class NodeCommunicateWebServiceImpl extends BaseService implements NodeCommunicateInterface {

	@SuppressWarnings("deprecation")
	Logger logger = Log.getExistLogger(LOGTYPE.TURBO);
	@Autowired
	NodeCommunicateService communicateService;
	@Autowired
	LocalConfCallBack localConfCallBack;
	@Autowired
	BaseInfoService baseInfoService;
	
	/**
	 * 发起
	 */
	@Override
	public NodeExchRelResponse receiveExchRelRequest(NodeExchRelVo nodeConnectRequest)
			throws ServiceException {
		NodeInfo fromNode = nodeConnectRequest.getFromNode();
		logger.info("交换关系建立-服务端：接收到请求，节点信息:\r\n"+fromNode);
		logger.info("交换关系建立-服务端：开始验证");
		NodeExchRelResponse response = new NodeExchRelResponse();
		//将注册请求入库
		ExchConnRequest connRequest = new ExchConnRequest();
		connRequest.setId(UUIDGenerator.getUUID());
		connRequest.setRequestType(ExchConnRequest.RequestType.EXCH_REL.getType());
		connRequest.setStatus(ExchConnRequest.RequestStatus.WAIT.getCode());
		connRequest.setRequestContent(JsonUtil.toJson(nodeConnectRequest));
		connRequest.setIsLocal(YESNO.NO.getStatus());
		connRequest.setMtime(new Date());
		NodeInfo localNode;
		try {
			localNode = communicateService.getLocalNodeInfo();
			if(localNode==null){
				response.setCode(SUCCESSFAIL.FAIL.getStatus());
				response.setMsg("目的节点未初始化！");
				logger.info("交换关系建立-服务端：验证失败，本地节点未初始化！");
				return response;
			}else if(fromNode==null){
				response.setCode(ExchConnRequest.RequestStatus.BLOCK.getCode());
				response.setMsg("节点信息不能为空！");
				logger.info("交换关系建立-服务端：验证失败，节点信息不能为空");
				return response;
			}/*else if(!communicateService.syncUrlIsValid(fromNode.getInstallUrl())){//验证同步地址的真确性
				//入库
				connRequest.setFromNodeId(fromNode.getId());
				connRequest.setStatus(ExchConnRequest.RequestStatus.BLOCK.getCode());
				connRequest.setResponse("系统自动阻止，请求节点同步地址错误["+fromNode.getInstallUrl()+"]");
				communicateService.insertOrUpdateConnRequest(connRequest);
				
				response.setCode(ExchConnRequest.RequestStatus.BLOCK.getCode());
				response.setMsg("节点同步地址无效！");
				logger.info("交换关系建立-服务端：验证失败，注册节点的同步地址无效");
				return response;
			}*/else if(communicateService.hasConnectRel(fromNode,localNode)){
				
				response.setCode(ExchConnRequest.RequestStatus.BLOCK.getCode());
				response.setMsg("已建立过交换关系！");
				logger.info("交换关系建立-服务端：验证失败，已建立过交换关系！");
				return response;
			}else if(communicateService.hasRequestAndWaitAuth(fromNode)){
				response.setCode(ExchConnRequest.RequestStatus.BLOCK.getCode());
				response.setMsg("已发送过请求，请勿重发，请联系接收方管理员审批！");
				logger.info("交换关系建立-服务端：请求失败，已发送过请求，请联系接收方管理员审批！！");
				return response;
			}
			else if(!communicateService.ifNetDomainSame(fromNode,localNode)){
				//验证网络是否匹配
				//入库
				connRequest.setFromNodeId(fromNode.getId());
				connRequest.setStatus(ExchConnRequest.RequestStatus.BLOCK.getCode());
				connRequest.setResponse("系统自动阻止，网络类型不匹配,本地网络类型为："+localNode.netTypeName()+"，请求节点类型为："+fromNode.netTypeName());
				communicateService.insertOrUpdateConnRequest(connRequest);
				
				response.setCode(ExchConnRequest.RequestStatus.BLOCK.getCode());
				response.setMsg("系统自动阻止，网络类型不匹配！需要类型："+localNode.netTypeName()+"，实际为："+fromNode.netTypeName());
				logger.info("系统自动阻止，网络类型不匹配！需要类型："+localNode.netTypeName()+"，实际为："+fromNode.netTypeName());
				return response;
			}else{
				logger.info("节点注册-服务端：验证成功！");
				//将注册请求入库
				connRequest.setToUrl(fromNode.getInstallUrl());
				connRequest.setFromNodeId(fromNode.getId());
				connRequest.setStatus(ExchConnRequest.RequestStatus.WAIT.getCode());
				connRequest.setResponse("系统自动验证已通过，需手动确认");
				CM.getDao().insertModule("插入建立关系请求", connRequest);
				communicateService.insertOrUpdateConnRequest(connRequest);
				
				response.setCode(ExchConnRequest.RequestStatus.WAIT.getCode());
				response.setMsg("待审批，请联系接收方管理员审批！");
				
				logger.info("交换关系建立-服务端：待审批，请联系接收方管理员审批！！");
				return response;
			}
		} catch (Exception e) {
			response.setCode(ExchConnRequest.RequestStatus.BLOCK.getCode());
			response.setMsg("接收方系统异常！"+e.getMessage());
			logger.error("交换关系建-服务端：系统异常！",e);
			return response;
		}
	}
	

	/**
	 * 注册节点接收到反馈的处理
	 * @throws ServiceException 
	 */
	@Override
	public NodeExchRelResponse receiveConnectResponse(NodeExchRelResponse callBack){
		String errorInfoNotBlock = null;
		String status = callBack.getCode();
		NodeExchRelVo responseData = (NodeExchRelVo)callBack.getData();
		NodeInfo remoteNode = responseData.getFromNode();
		NodeExchRelResponse relResponse = new NodeExchRelResponse();
		ExchConnRequest connRequestLocal = null ;
		try {
			connRequestLocal = communicateService.getLocalWaitAuthRegistRequest(remoteNode.getInstallUrl().toLowerCase());
		} catch (Exception e) {
			logger.error("交换关系建立-服务端：失败,获取请求记录失败,",e);
			relResponse.setMsg("请求方接收审核结果失败，远端系统异常...");
			relResponse.setCode(SUCCESSFAIL.FAIL.getStatus());
			communicateService.updateRequestStatus(connRequestLocal, ExchConnRequest.RequestStatus.ERROR, "系统异常");
			return relResponse;
		}
		if(connRequestLocal==null){
			logger.error("交换关系建立-服务端：失败,请求已不存在");
			relResponse.setMsg("请求方接收审核结果失败，请求已不存在...");
			relResponse.setCode(SUCCESSFAIL.FAIL.getStatus());
			communicateService.updateRequestStatus(connRequestLocal, ExchConnRequest.RequestStatus.BLOCK, "系统异常");
			return relResponse;
		}else{
			if(ExchConnRequest.RequestStatus.BLOCK.getCode().endsWith(status)){
				//被拒绝了。
				relResponse.setCode(SUCCESSFAIL.SUCCESS.getStatus());
				communicateService.updateRequestStatus(connRequestLocal, ExchConnRequest.RequestStatus.BLOCK, callBack.getMsg());
				return relResponse;
			}else if(ExchConnRequest.RequestStatus.PASS.getCode().endsWith(status)){
				try {
					List<NodePipeline> remoteNodePipeLines = responseData.getPipeLines();
					/*List<SysInfo> remoteNodeSysInfos = responseData.getSysInfos();*/
					List<DomainInfo> domainInfos = responseData.getDomainInfos();
					//1 同步过来信息(节点信息，通道信息,注册系统信息)入库
					remoteNode.setIsLocal(YESNO.NO.getStatus());
					communicateService.insertOrUpdateRemoteNode(remoteNode);
					communicateService.insertOrUpdateRemotePipeLineInfo(remoteNodePipeLines);
					//communicateService.insertOrUpdateRemoteSysInfo(remoteNodeSysInfos);
					communicateService.insertOrUpdateRemoteDomains(domainInfos);
					//插入交换关系
					NodeInfo localNode = communicateService.getLocalNodeInfo();
					communicateService.insertExchRel(localNode,remoteNode);
					try {
						localConfCallBack.onNodeExchRelCreate(localNode, remoteNode);
					} catch (Exception e) {
						errorInfoNotBlock = "交换关系建立成功，但分配通道资源失败，请手动处理...";
						logger.error(e);
					}
					relResponse.setCode(SUCCESSFAIL.SUCCESS.getStatus());
					communicateService.updateRequestStatus(connRequestLocal, ExchConnRequest.RequestStatus.PASS, StringUtils.hasText(errorInfoNotBlock)?errorInfoNotBlock:"通过");
					return relResponse;
				} catch (Exception e) {
					logger.error("交换关系建立-服务端：失败,",e);
					relResponse.setMsg("请求方接收审核结果失败，远端系统异常...");
					relResponse.setCode(SUCCESSFAIL.FAIL.getStatus());
					communicateService.updateRequestStatus(connRequestLocal, ExchConnRequest.RequestStatus.ERROR, "系统异常");
					return relResponse;
				}
			}else{
				return relResponse;
			}
		}
	}
	
    
	@Override
	public NodeExchRelResponse receiveSyncInfo(SynchronizeInfo synchronizeInfo) {
		NodeExchRelResponse exchRelResponse = new NodeExchRelResponse();
		try {
			boolean hasRel = communicateService.hasExchRel(synchronizeInfo.getFromNode(), synchronizeInfo.getToNode());
			if(!hasRel){
				logger.error("接收同步信息错误，没有建立交换关系！");
				exchRelResponse.setMsg("接收同步信息错误，没有建立交换关系！");
				exchRelResponse.setCode(SUCCESSFAIL.FAIL.getStatus());
				return exchRelResponse;
			}
		} catch (ServiceException e1) {
			logger.error("接收同步信息错误，系统异常！",e1);
			exchRelResponse.setMsg("接收同步信息错误，目的系统异常！");
			exchRelResponse.setCode(SUCCESSFAIL.FAIL.getStatus());
			return exchRelResponse;
		}
		
		if(synchronizeInfo==null||!StringUtils.hasText(synchronizeInfo.getDataContent())){
			logger.error("接收同步信息错误，信息为空！");
			exchRelResponse.setMsg("接收同步信息错误，信息为空！");
			exchRelResponse.setCode(SUCCESSFAIL.FAIL.getStatus());
			return exchRelResponse;
		}else if(!StringUtils.hasText(synchronizeInfo.getFromNode())){
			logger.error("接收同步信息错误，发送节点信息为空！");
			exchRelResponse.setMsg("接收同步信息错误，发送节点信息为空！");
			exchRelResponse.setCode(SUCCESSFAIL.FAIL.getStatus());
			return exchRelResponse;
		}else{
			try {
				logger.info("接收到同步信息,来自["+synchronizeInfo.getFromNodeName()+"]，->"+synchronizeInfo);
				String dateType = synchronizeInfo.getDataType();
//				String operation = synchronizeInfo.getOperType();
//				boolean delete = SyncOperType.DELETE.getCode().equals(operation);
				if(SyncType.NODE_INFO.getCode().equals(dateType)){
					NodeInfo nodeInfo = JsonUtil.toObject(synchronizeInfo.getDataContent(), NodeInfo.class);
					nodeInfo.setIsLocal(YESNO.NO.getStatus());
					communicateService.insertOrUpdateRemoteNode(nodeInfo);
					
				}else if(SyncType.PILE_LINE.getCode().equals(dateType)){
					NodePipeline pipeLine = JsonUtil.toObject(synchronizeInfo.getDataContent(), NodePipeline.class);
					pipeLine.setIsLocal(YESNO.NO.getStatus());
					communicateService.insertOrUpdateRemotePipeLineInfo(pipeLine);
				}else if(SyncType.DOMAIN_INFO.getCode().equals(dateType)){
					DomainInfo domainInfo = JsonUtil.toObject(synchronizeInfo.getDataContent(), DomainInfo.class);
					communicateService.insertOrUpdateRemoteDomainNode(domainInfo);
				}else{
					logger.error("接收同步信息错误，不支持的同步类型->"+dateType);
					exchRelResponse.setMsg("接收同步信息错误，不支持的同步类型->"+dateType);
					exchRelResponse.setCode(SUCCESSFAIL.FAIL.getStatus());
					return exchRelResponse;
				}
				logger.info("接收同步信息,来自["+synchronizeInfo.getFromNodeName()+"]，成功.");
				exchRelResponse.setMsg("接收同步信息成功");
				exchRelResponse.setCode(SUCCESSFAIL.SUCCESS.getStatus());
				return exchRelResponse;
			} catch (Exception e) {
				logger.error("接收同步信息失败",e);
				exchRelResponse.setMsg("接收同步信息失败，系统异常，请联系节点["+synchronizeInfo.getToNodeName()+"]");
				exchRelResponse.setCode(SUCCESSFAIL.FAIL.getStatus());
				return exchRelResponse;
			}
		}
	}


	@Override
	public NodeExchRelResponse deleteNodeRel(String fromNodeId, String toNodeId) {
		//删除
		return null;
	}

}
